package service

import (
	"context"
	"errors"
	"insighttracking/common/enum"
	"insighttracking/common/utils"
	"insighttracking/query/bo"
	"insighttracking/query/dao"
	"insighttracking/query/model"
)

type _productionPlanService struct{}

func (s _productionPlanService) CreateApi(ctx context.Context, tx *dao.QueryTx, req *model.ProductionPlanEntity) (id int64, err error) {
	if err = tx.ProductionPlanEntity.WithContext(ctx).Create(req); err != nil {
		return 0, errors.New("创建失败")
	}
	return req.ID, nil
}

func (s _productionPlanService) CreateDetailApi(ctx context.Context, tx *dao.QueryTx, req []*model.ProductionPlanDetailEntity) (err error) {
	if err = tx.ProductionPlanDetailEntity.WithContext(ctx).CreateInBatches(req, len(req)); err != nil {
		return errors.New("创建失败")
	}
	return
}

func (s _productionPlanService) ModifyStatusByIdsApi(ctx context.Context, ids []int64, status int64) (err error) {
	_, err = dao.ProductionPlanDetailEntity.WithContext(ctx).Where(dao.ProductionPlanDetailEntity.ID.In(ids...)).UpdateColumn(dao.ProductionPlanDetailEntity.Status, status)
	return
}

func (s _productionPlanService) CreatePlanOrderRelationApi(ctx context.Context, tx *dao.QueryTx, req []*model.ProductionOrdersEntity) (err error) {
	if err = tx.ProductionOrdersEntity.WithContext(ctx).CreateInBatches(req, len(req)); err != nil {
		return errors.New("创建失败")
	}
	return
}

func (s _productionPlanService) GetListApi(ctx context.Context, enterpriseId int64, beginDate string, endDate string) (resp []*model.ProductionPlanEntity, err error) {
	resp, err = dao.ProductionPlanEntity.WithContext(ctx).Where(
		dao.ProductionPlanEntity.ProduceDate.Between(utils.DateStrToTime(beginDate), utils.DateStrToTime(endDate)),
		dao.ProductionPlanEntity.EnterpriseID.Eq(enterpriseId),
	).Find()
	return
}

func (s _productionPlanService) GetDetailListApi(ctx context.Context, productionPlanId int64) (resp []*bo.ProductionPlanDetailBo, err error) {
	err = dao.ProductionPlanDetailEntity.WithContext(ctx).
		Select(dao.ProductionPlanDetailEntity.ALL, dao.SpuEntity.Name.As("SpuName")).
		LeftJoin(dao.SpuEntity, dao.SpuEntity.ID.EqCol(dao.ProductionPlanDetailEntity.SpuID)).
		Where(dao.ProductionPlanDetailEntity.ProductionPlanID.Eq(productionPlanId)).Scan(&resp)
	return
}

func (s _productionPlanService) GetPlanOrdersApi(ctx context.Context, productionPlanId int64) (resp []int64, err error) {
	err = dao.ProductionOrdersEntity.WithContext(ctx).Where(dao.ProductionOrdersEntity.ProductionPlanID.Eq(productionPlanId)).
		Pluck(dao.ProductionOrdersEntity.OrdersID, &resp)
	return
}

func (s _productionPlanService) GetInfoByIdApi(ctx context.Context, id int64) (resp *model.ProductionPlanEntity, err error) {
	resp, err = dao.ProductionPlanEntity.WithContext(ctx).Where(
		dao.ProductionPlanEntity.ID.Eq(id)).First()
	return
}

func (s _productionPlanService) PublishTaskApi(ctx context.Context, req []*model.PickingTaskEntity) (err error) {
	return dao.PickingTaskEntity.WithContext(ctx).CreateInBatches(req, len(req))
}

func (s _productionPlanService) RemoveTaskApi(ctx context.Context, enterpriseID int64, productionDetailID []int64) (err error) {
	_, err = dao.PickingTaskEntity.WithContext(ctx).Where(dao.PickingTaskEntity.EnterpriseID.Eq(enterpriseID),
		dao.PickingTaskEntity.ProductionPlanDetailID.In(productionDetailID...)).Delete()
	return
}

func (s _productionPlanService) GetDetailListByIDs(ctx context.Context, ids []int64) (resp []*bo.ProductionPlanDetailBo, err error) {
	err = dao.ProductionPlanDetailEntity.WithContext(ctx).
		Select(
			dao.ProductionPlanDetailEntity.ALL, dao.SpuEntity.Name.As("SpuName"),
			dao.SpuBomEntity.OrgSpuID.As("OrgSpuID"),
			dao.SpuBomEntity.OrgSpuName.As("OrgSpuName"),
			dao.SpuEntity.LossRate.As("LossRate"),
		).
		LeftJoin(dao.SpuEntity, dao.SpuEntity.ID.EqCol(dao.ProductionPlanDetailEntity.SpuID)).
		LeftJoin(dao.SpuBomEntity, dao.SpuBomEntity.SpuID.EqCol(dao.ProductionPlanDetailEntity.SpuID)).
		Where(dao.ProductionPlanDetailEntity.ID.In(ids...)).Scan(&resp)
	return
}

func (s _productionPlanService) GetActivityDetailsBySpuID(ctx context.Context, enterpriseID int64, spuID int64) (resp []*bo.ProductionPlanAndDetailIDBo, err error) {
	err = dao.ProductionPlanDetailEntity.WithContext(ctx).
		Select(dao.ProductionPlanDetailEntity.ID, dao.ProductionPlanEntity.Name, dao.ProductionPlanEntity.Code).
		LeftJoin(dao.ProductionPlanEntity, dao.ProductionPlanEntity.ID.EqCol(dao.ProductionPlanDetailEntity.ProductionPlanID)).
		Where(dao.ProductionPlanDetailEntity.Status.Eq(enum.ProductionStatusLoading),
			dao.ProductionPlanDetailEntity.SpuID.Eq(spuID),
			dao.ProductionPlanEntity.EnterpriseID.Eq(enterpriseID),
		).Scan(&resp)
	return
}

func (s _productionPlanService) GetInOutDetailApi(ctx context.Context, enterPriseID, productionID int64, spuID, pageSize, pageNumber int64) (resp []*bo.ProductionPlanInOutDetailBo, count int64, err error) {
	tx := dao.ProductionPlanDetailEntity.WithContext(ctx).
		Select(
			dao.ProductionPlanDetailEntity.ID.As("ProductionPlanDetailID"),
			dao.ProductionPlanDetailEntity.CreatedAt,
			dao.SpuBomEntity.SpuName.As("ProcessSpuName"),
			dao.SpuBomEntity.SpuID.As("ProcessSpuID"),
			dao.SpuBomEntity.Code.As("ProcessSpuBOMCode"),
			dao.SpuBomEntity.OrgSpuName.As("BaseSpuName"),
			dao.SpuBomEntity.OrgSpuID.As("BaseSpuID"),
			dao.SpuBomEntity.ProductionLineIds.As("ProductionLines"),
			dao.ProductionPlanEntity.ID.As("ProductionPlanID"),
			dao.ProductionPlanEntity.Name.As("ProductionPlanName")).
		LeftJoin(dao.SpuBomEntity, dao.SpuBomEntity.SpuID.EqCol(dao.ProductionPlanDetailEntity.SpuID)).
		LeftJoin(dao.ProductionPlanEntity, dao.ProductionPlanEntity.ID.EqCol(dao.ProductionPlanDetailEntity.ProductionPlanID)).
		Where(dao.ProductionPlanEntity.EnterpriseID.Eq(enterPriseID), dao.SpuBomEntity.SpuID.IsNotNull())

	if productionID != 0 {
		tx = tx.Where(dao.ProductionPlanDetailEntity.ProductionPlanID.Eq(productionID))
	}
	if spuID != 0 {
		tx = tx.Where(dao.ProductionPlanDetailEntity.SpuID.Eq(productionID))
	}
	offset, limit := utils.DbPage(pageNumber, pageSize)
	count, err = tx.ScanByPage(&resp, offset, limit)
	return
}

func (s _productionPlanService) GetTypeCountByPlanIDApi(ctx context.Context, productionPlanId int64) (count int64, err error) {
	return dao.ProductionPlanDetailEntity.WithContext(ctx).Where(dao.ProductionPlanDetailEntity.ProductionPlanID.Eq(productionPlanId)).Count()
}

func (s _productionPlanService) GetProductionByDetailIDApi(ctx context.Context, productionPlanDetailId int64) (entity *model.ProductionPlanEntity, err error) {
	err = dao.ProductionPlanDetailEntity.WithContext(ctx).Select(dao.ProductionPlanEntity.ALL).
		LeftJoin(dao.ProductionPlanEntity, dao.ProductionPlanEntity.ID.EqCol(dao.ProductionPlanDetailEntity.ProductionPlanID)).
		Where(dao.ProductionPlanDetailEntity.ID.Eq(productionPlanDetailId)).Scan(&entity)
	return
}

var ProductionPlanService = new(_productionPlanService)
